import sys

from argparse import ArgumentParser, Namespace
from typing import Any, Callable, Optional, Sequence

from fenrispunk_tools.business.map_generator import generate_map_defaults
from fenrispunk_tools.business.tile_generator import generate_tile_defaults


def get_tools_name() -> str:
    return "fenrispunk_tools"


def get_mode_option_help() -> str:
    return "help"


def get_mode_option_maps() -> str:
    return "maps"


def get_mode_option_tiles() -> str:
    return "tiles"


def get_mode_options() -> list:
    return [
        get_mode_option_help(),
        get_mode_option_maps(),
        get_mode_option_tiles(),
    ]


def get_description() -> str:
    return f"{get_tools_name()} helps generate sprite art for use with ttrpgs."


def get_mode_options_help() -> None:
    print("modes:")
    for option in get_mode_options():
        print(f"  {option}")


def get_parser() -> ArgumentParser:
    parser = ArgumentParser(description=get_description())
    parser.add_argument(
        "-g",
        "--grid",
        help="Grid path containing the char map",
    )
    parser.add_argument(
        "-t",
        "--tiles",
        help="Tiles path containing the sprite set",
    )
    parser.add_argument(
        "-i",
        "--image-data",
        help="Image data path containing the RGB",
    )
    parser.add_argument(
        "-o",
        "--output",
        help="Output path",
    )
    parser.add_argument(
        "mode",
        metavar="mode",
        help="Modes of operation",
        choices=get_mode_options(),
        type=str.lower,
        nargs="?",
        default=None,
    )
    parser.add_argument(
        "commands",
        help="Mode commands",
        nargs="*",
        default=None,
    )
    return parser


def process_with_argparsed(args: Namespace, help_func: Callable) -> None:
    if args.mode not in get_mode_options():
        help_func()
        get_mode_options_help()

    elif args.mode == get_mode_option_help() and args.commands:
        if args.commands[0] not in get_mode_options():
            print(f"{args.commands[0]} not recognized")
            help_func()
            get_mode_options_help()
        if args.commands[0] == get_mode_option_maps():
            print(f"{get_tools_name()} {args.commands[0]}")
            print("Generate maps from text files using sprite maps.")
        if args.commands[0] == get_mode_option_tiles():
            print(f"{get_tools_name()} {args.commands[0]}")
            print("Generate tiles from text files.")

    elif args.mode == get_mode_option_help():
        help_func()
        get_mode_options_help()

    elif args.mode == get_mode_option_maps():
        generate_map_defaults(args.output, args.grid, args.tiles)

    elif args.mode == get_mode_option_tiles():
        generate_tile_defaults(args.output, args.image_data)


def client_parse_args(parser: ArgumentParser, args: Optional[Sequence[str]]) -> None:
    process_with_argparsed(
        parser.parse_args(args),
        parser.print_help,
    )


def get_args_to_parse(args: dict) -> Optional[Sequence[str]]:
    return args[1:]


def tools_main(args: dict) -> None:
    client_parse_args(get_parser(), get_args_to_parse(args))
